﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace VisualPureBasicIDE.CoreGUI.Extensibility
{
    public static class PluginManager
    {
        static List<IPlugin> _plugins;

        /// <summary>
        /// Gets or sets a list of the loaded plugins
        /// </summary>
        public static List<IPlugin> Plugins
        {
            get
            {
                if (_plugins == null) _plugins = new List<IPlugin>();

                return _plugins;
            }
            set
            {
                _plugins = value;
            }
        }

        /// <summary>
        /// Loads all existing plugins in the folder "plugins" and adds them to the "_plugins" list
        /// </summary>
        public static void InstantiateAndLoadAllPlugins()
        {
            IPlugin plugin;

            if (!Directory.Exists(InvariantStrings.PluginPath))
            {
                // Plugin folder doesn't exist, so create one now
                try { Directory.CreateDirectory(InvariantStrings.PluginPath); }
                catch (Exception ex)
                {
                    MessageBox.Show(Translator.GetStringAndTranslate("strCreatingPluginFolderError"), Translator.GetStringAndTranslate("strError"), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    Logger.SendException(ex);
                }
                return;
            }

            // Get plugin folder info
            var pluginDir = new DirectoryInfo(InvariantStrings.PluginPath);

            foreach (var file in pluginDir.GetFiles())
            {
                if (file.Extension.ToUpper() != ".DLL") continue;

                var pluginMainClass = file.Name.Split('.')[0];
                try
                {
                    // Try to activate the plugin and unwrap it
                    var oHandle = Activator.CreateInstanceFrom(file.FullName, "VisualPureBasicIDE.PluginArchitecture.Plugins." + pluginMainClass);
                    if (oHandle == null) continue;

                    plugin = oHandle.Unwrap() as IPlugin;

                    // Add it to the manager
                    Plugins.Add(plugin);

                    // Make an appropriate ToolStripItem in pluginActionsToolStripMenuItem and pass it to the plugin
                    if (plugin == null) continue;
                    plugin.MenuItem = ApplicationManager.MainForm.CreatePluginMenuItem(plugin);

                    // Load the plugin
                    plugin.Load();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(Translator.GetStringAndTranslate("strLoadingPluginErrorPart1") + '"' + file.Name + '"' + Translator.GetStringAndTranslate("strLoadingPluginErrorPart2"), Translator.GetStringAndTranslate("strError"), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    Logger.SendException(ex);
                }
            }
        }

        /// <summary>
        /// Unloads all plugins in the list
        /// </summary>
        public static void UnloadAllPlugins()
        {
            foreach (var plugin in _plugins)
                plugin.Unload();
        }

        /// <summary>
        /// Reloads all plugins in the list
        /// </summary>
        public static void ReloadAllPlugins()
        {
            UnloadAllPlugins();

            foreach (var plugin in _plugins)
                plugin.Load(); // it's simple, huh?
        }
    }
}